package com.huishi.handler.thread.task;

import com.huishi.entity.DataSource;
import com.huishi.handler.thread.ThreadDataKeeper;
import com.huishi.util.DBUtils;
import com.huishi.util.FileUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Queue;

@Slf4j
public class Reader implements Runnable {

    private final DataSource sourceDS; // 源数据源
    private final String sourceDB; // 源库名
    private final List<String> tables;
    private final ThreadDataKeeper threadDataKeeper;

    public Reader(DataSource sourceDS, String sourceDB, List<String> tables, ThreadDataKeeper threadDataKeeper) {
        this.sourceDS = sourceDS;
        this.sourceDB = sourceDB;
        this.tables = tables;
        this.threadDataKeeper = threadDataKeeper;

        this.threadDataKeeper.setSourceDS(sourceDS);
        this.threadDataKeeper.setSourceDB(sourceDB);
    }

    @Override
    public void run() {
        Queue<String> executeSqlFile = threadDataKeeper.getExecuteSqlFile();// 待执行sql文件
        String sqlFilePath = FileUtils.getCurrentAbsolutePath() + "/temp" + System.currentTimeMillis() + "/"; // sql文件路径
        threadDataKeeper.setSqlFilePath(sqlFilePath);
        FileUtils.createFolder(sqlFilePath); // 创建暂存sql文件的文件夹

        int batchSize = 100000;// 表批次同步数据量

        // 0开始同步
        threadDataKeeper.getProgressDialog().startTimer();

        for (String table : tables) {
            // 1导出表结构
            String tableStructureSql = sqlFilePath + table + "-structure.sql";
            if (DBUtils.backupTableStructure(sourceDS.getIp(), sourceDS.getPort(), sourceDS.getUserName(), sourceDS.getPassword(), sourceDB, table, tableStructureSql)) {
                log.info("导出表结构：{}", tableStructureSql);
                synchronized (threadDataKeeper.getExecuteSqlFile()) {
                    executeSqlFile.add(tableStructureSql);
                    executeSqlFile.notifyAll();
                }
            }

            // 2查询表总记录数
            int totalRow = DBUtils.getTotalRow(sourceDS.getIp(), sourceDS.getPort(), sourceDS.getUserName(), sourceDS.getPassword(), sourceDB, table);

            // 3分批次导出表数据
            // 批次导出数量
            int batches = totalRow / batchSize;
            for (int i = 0; i <= batches; i++) {
                String tableBatchSql = sqlFilePath + table + "-data" + i + ".sql";
                if (DBUtils.backupDataBatch(sourceDS.getIp(), sourceDS.getPort(), sourceDS.getUserName(), sourceDS.getPassword(), sourceDB, table, i * batchSize, batchSize, tableBatchSql)) {
                    log.info("批次导出表数据：{}", tableBatchSql);
                    synchronized (threadDataKeeper.getExecuteSqlFile()) {
                        executeSqlFile.add(tableBatchSql);
                        executeSqlFile.notifyAll();
                    }
                }
            }
        }

        log.info("read finished");
        threadDataKeeper.setWriterRun(Boolean.FALSE);
    }
}
